﻿using System.Collections;
using System.Collections.Generic;

using UnityEngine;

//[ExecuteInEditMode]
public partial class UGUISortingOrder : UnityEngine.EventSystems.UIBehaviour
{
    [SerializeField]
    private int layerIndex;

    private List<ushort> sortingId = new List<ushort>();

    private Canvas _canvas;
    private Renderer _renderer;

    private bool isRegisted;

    // temp 
    private int siblingIndex = 0;

    public List<ushort> SortingId
    {
        get { return sortingId; }
    }

    public int LayerIndex
    {
        set { layerIndex = value; }
        get { return layerIndex; }
    }

    protected override void Awake()
    {
        _canvas = GetComponent<Canvas>();
        _renderer = GetComponent<Renderer>();
    }

    protected override void OnEnable()
    {
        // temp 
        siblingIndex = transform.GetSiblingIndex();
        RegistParNode();
    }

    protected override void OnDisable()
    {
        UnRegistParNode();
    }

    void Update()
    {
        if (!isRegisted)
        {
            RegistParNode();
        }
        else
        {
            if (transform.GetSiblingIndex() != siblingIndex)
            {
                siblingIndex = transform.GetSiblingIndex();
                HierarchyChanged();
            }
        }
    }

    private void RegistParNode()
    {
        if (null == _canvas && null == _renderer)
        {
        }

        if (isRegisted)
        {
            UnRegistParNode();
        }

        sortingId.Clear();

        List<ushort> temp = GetSelfHierarchySortingID();
        if (null != temp)
        {
            sortingId.AddRange(temp);
        }

        if (sortingId.Count == 0)
        {
            isRegisted = false;
            return;
        }

        if (null != ASortingOrderManager.Instance)
        {
            ASortingOrderManager.Instance.RegistChildNode(this);
            isRegisted = true;
        }
    }

    private void UnRegistParNode()
    {
        if (isRegisted)
        {
            ASortingOrderManager.Instance.UnRegistChildNode(this);

            isRegisted = false;
        }
    }

    protected override void OnTransformParentChanged()
    {
        base.OnTransformParentChanged();
        HierarchyChanged();
    }

    private List<ushort> GetSelfHierarchySortingID()
    {
        List<ushort> newSortingId = new List<ushort>();

        ASortingOrderManager sortingScript = null;
        Transform tempPar = transform;

        while (null == sortingScript)
        {
            newSortingId.Insert(0, (ushort)tempPar.GetSiblingIndex());
            tempPar = tempPar.parent;
            if (null == tempPar)
            {
                //Debug.LogError("Parent is null!!!Script mount a wrong position!!!");
                return null;
            }
            sortingScript = tempPar.GetComponent<ASortingOrderManager>();
        }

        return newSortingId;
    }

    public void SetCanvasLayer(int layerIndex)
    {
        this.layerIndex = layerIndex;
        if (_canvas)
        {
            _canvas.overrideSorting = true;
            _canvas.sortingLayerID = 0;
            _canvas.sortingOrder = layerIndex;
        }

        if (_renderer)
        {
            _renderer.sortingLayerID = 0;
            _renderer.sortingOrder = layerIndex;
        }
    }

    public void HierarchyChanged()
    {
        List<ushort> newSortingID = GetSelfHierarchySortingID();
        sortingId.Clear();
        if(newSortingID!=null)
            sortingId.AddRange(newSortingID);
        if (ASortingOrderManager.Instance.IsChildRelativePathChanged(this))
        {
            UnRegistParNode();
            RegistParNode();

            // temp
            UGUISortingOrder[] children = GetComponentsInChildren<UGUISortingOrder>();

            if (null != children && children.Length > 0)
            {
                for (int i = 0; i < children.Length; ++i)
                {
                    children[i].HierarchyChanged();
                }
            }
        }
        else
        {
            UGUISortingOrder[] children = GetComponentsInChildren<UGUISortingOrder>();

            if (null != children && children.Length > 0)
            {
                for (int i = 0; i < children.Length; ++i)
                {
                    children[i].UpdataSortingId();
                }
            }
        }
    }

    public void UpdataSortingId()
    {
        sortingId.Clear();
        var listId = GetSelfHierarchySortingID();
        if(listId!=null)
            sortingId.AddRange(listId);
    }

    public static int CompareSortingId(List<ushort> sortingId1, List<ushort> sortingId2)
    {
        if (null == sortingId1 || null == sortingId2)
        {
            Debug.LogError("Method CompareSortingId param is null!!!");
            return -1;
        }
        int sortingId1Length = sortingId1.Count;
        int sortingId2Length = sortingId2.Count;

        int compareNum = sortingId1Length < sortingId2Length ? sortingId1Length : sortingId2Length;

        for (int i = 0; i < compareNum; ++i)
        {
            if (sortingId1[i] == sortingId2[i])
            {
                continue;
            }
            if (sortingId1[i] > sortingId2[i])
            {
                return -1;
            }
            else
            {
                return 1;
            }
        }

        if (sortingId1Length == sortingId2Length)
        {
            return 0;
        }

        return sortingId1Length > sortingId2Length ? -1 : 1;
    }

}